using System;
using System.Diagnostics;
using System.IO;
using System.Text;
using iTextSharp.text; // iTextSharp is downloadable from http://itextsharp.sourceforge.net/ - Copyright 1999-2008 by Bruno Lowagie and Paulo Soares. All Rights Reserved.
using iTextSharp.text.pdf;
using RecruitmentAgency.Models.DataTypes;

namespace RecruitmentAgency.Models.Utilities
{
    /// <summary>
    /// The RecruitmentAgency.Models.Utilities.PdfDocumentCreator is a helper class that uses the iTextSharp.text classes to create and opens a CV in PDF format from a CvData instance
    /// </summary>
    public class PdfDocumentCreator
    {
        private Document document;
        private PdfWriter pdfWriter;
        private string filePath;

        /// <summary>
        /// Initialises a new RecruitmentAgency.Models.Utilities.PdfDocumentCreator instance
        /// </summary>
        public PdfDocumentCreator(string filePath)
        {
            this.filePath = filePath;
            document = new Document();
            pdfWriter = PdfWriter.GetInstance(document, new FileStream(filePath, FileMode.Create));
            document.Open();
        }

        /// <summary>
        /// Creates and opens a CV in PDF format from a CvData instance
        /// </summary>
        /// <param name="cvData">The CV data to create the PDF with</param>
        public void CreatePdfFromCvData(CvData cvData)
        {
            // set up document fonts
            BaseFont helvetica = BaseFont.CreateFont(@"Helvetica", BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
            Font heading = new Font(helvetica, 20.0f, Font.BOLD);
            Font title = new Font(helvetica, 14.0f, Font.BOLD);
            Font main = new Font(helvetica, 12.0f, Font.NORMAL);
            Font bold = new Font(helvetica, 13.0f, Font.BOLD);
            Font italic = new Font(helvetica, 12.0f, Font.ITALIC);
            // perform intelligent string building
            PersonalDetail personalDetail = cvData.PersonalDetail;
            string middleNames = string.IsNullOrEmpty(personalDetail.MiddleNames) ? string.Empty : " " + personalDetail.MiddleNames;
            string fullName = string.Format("{0}{1} {2}", personalDetail.FirstName, middleNames, personalDetail.LastName);
            StringBuilder address = new StringBuilder(personalDetail.AddressLine1 + ", ");
            if (!string.IsNullOrEmpty(personalDetail.AddressLine2)) address.Append(personalDetail.AddressLine2 + ", ");
            address.Append(personalDetail.Town + ", ");
            address.Append(personalDetail.PostCode);
            StringBuilder contacts = new StringBuilder();
            if (!string.IsNullOrEmpty(personalDetail.HomePhone)) contacts.Append(personalDetail.HomePhone);
            if (!string.IsNullOrEmpty(personalDetail.MobilePhone))
            {
                if (contacts.Length > 0) contacts.Append(" / ");
                contacts.Append(personalDetail.MobilePhone);
            }
            if (!string.IsNullOrEmpty(personalDetail.Email1))
            {
                if (contacts.Length > 0) contacts.Append(" / ");
                contacts.Append(personalDetail.Email1);
            }
            if (!string.IsNullOrEmpty(personalDetail.Email2))
            {
                if (contacts.Length > 0) contacts.Append(" / ");
                contacts.Append(personalDetail.Email2);
            }
            // add user photo if one exists
            float margin = 0;
            if (!string.IsNullOrEmpty(personalDetail.PhotoUrl))
            {
                margin = 30f;
                Image userPhoto = Image.GetInstance(new Uri(personalDetail.PhotoUrl));
                //userPhoto.Alignment = Image.RIGHT_ALIGN | Image.TEXTWRAP;
                Chunk chunk = new Chunk(userPhoto, 0, 0);
                document.Add(new Paragraph(userPhoto.Height, chunk));
            }
            // add CV details
            document.Add(new Paragraph(margin, fullName, heading));
            document.Add(new Paragraph(address.ToString(), bold));
            document.Add(new Paragraph(contacts.ToString(), bold));
            if (!string.IsNullOrEmpty(personalDetail.WebsiteUrl)) document.Add(new Paragraph("www." + personalDetail.WebsiteUrl, bold));
            if (!string.IsNullOrEmpty(personalDetail.DateOfBirth)) document.Add(new Paragraph(DateTime.Parse(personalDetail.DateOfBirth).ToLongDateString(), bold));
            document.Add(new Paragraph(" "));
            if (cvData.PersonQualifications.Count > 0)
            {
                document.Add(new Paragraph("Qualifications", title));
                foreach (PersonQualification qualification in cvData.PersonQualifications)
                {
                    if (qualification.QualificationVerified)
                    {
                        document.Add(new Paragraph("\u2022 " + qualification.ToShortString(), main));
                    }
                }
                document.Add(new Paragraph(" "));
            }
            if (cvData.PersonEmployments.Count > 0)
            {
                document.Add(new Paragraph("Employment record", title));
                foreach (PersonEmployment employment in cvData.PersonEmployments)
                {
                    if (employment.EmploymentVerified)
                    {
                        string employmentString = string.Format(string.Format("Worked as a {0} at {1} from {2} to {3} in the {4} sector.", employment.JobTitle, employment.CompanyName, (DateTime.Parse(employment.StartDate)).ToLongDateString(), (DateTime.Parse(employment.EndDate)).ToLongDateString(), employment.IndustrySector));
                        document.Add(new Paragraph(employment.ToLongString(), main));
                        document.Add(new Paragraph("\u2022 " + employment.KeyDuties, italic));
                        document.Add(new Paragraph(" "));
                    }
                }
            }
            if (cvData.PersonSkills.Count > 0)
            {
                document.Add(new Paragraph("Current skills", title));
                foreach (PersonSkill skill in cvData.PersonSkills)
                {
                    if (skill.SkillVerified)
                    {
                        document.Add(new Paragraph("\u2022 " + skill.ToShortString(), main));
                    }
                }
                document.Add(new Paragraph(" "));
            }
            if (cvData.PersonReferees.Count > 0)
            {
                document.Add(new Paragraph("Referees", title));
                foreach (PersonReferee referee in cvData.PersonReferees)
                {
                    if (referee.RefereeVerified)
                    {
                        address = new StringBuilder(referee.RefereeAddressLine1 + ",\n");
                        if (!string.IsNullOrEmpty(referee.RefereeAddressLine2)) address.Append(referee.RefereeAddressLine2 + ",\n");
                        address.Append(referee.RefereeTown + ",\n");
                        address.Append(referee.RefereePostCode);
                        document.Add(new Paragraph(referee.RefereeFirstName + " " + referee.RefereeLastName, main));
                        document.Add(new Paragraph(address.ToString(), main));
                        document.Add(new Paragraph(referee.RefereePhone, main));
                        document.Add(new Paragraph(referee.Email, main));
                        document.Add(new Paragraph(" "));
                    }
                }
            }
            document.Close();
            Process.Start(filePath);
        }
    }
}